home *** CD-ROM | disk | FTP | other *** search
/ Merciful 2 / Merciful - Disc 2.iso / software / d / dustv1.91.lha / Dust / Tutorial3 / Source / PExampleGCC.c < prev   
C/C++ Source or Header  |  1994-09-26  |  12KB  |  359 lines

  1. /*
  2. ###############################################################################
  3. #                                                                             #
  4. #                 Dust V1.04 - Copyright ©1994 by A.Maschke                   #
  5. #                           All rights reserved.                              #
  6. #-----------------------------------------------------------------------------#
  7. #                                                                             #
  8. #              Tutorial 3: Create a particle-explosion using Dust             #
  9. #                            -changes only particle-positions                 #
  10. #                            -writes scriptfile to stdout                     #
  11. #                                                                             #
  12. # OPERATION: 1. write a script which creates a particle-object and outputs    #
  13. #               the PPOS-array and OCOUNT, e.g.:                              #
  14. #                "load(1,objects/s1)                                          #
  15. #                 load(2,objects/c1)                                          #
  16. #                 set(EXFORMAT,LONG)                                          #
  17. #                 o2p(1,2,1,p)                                                #
  18. #                 savep(1,PExample.obj)                                       #
  19. #                 getocount(1)                                                #
  20. #                 !copy T:Dust.output PExample.oCount                         #
  21. #                 getppos(1)                                                  #
  22. #                 !copy T:Dust.output PExampleGCC.PPOS                        #
  23. #                 !delete T:Dust.output                                       #
  24. #                 exit"                                                       #
  25. #               As you can see the EXFILE has to be in LONG-format, because   #
  26. #               GCC can't read the floating-point-numbers saved by Dust.      #
  27. #               So we have to "decrypt" our floats (long/65536.0=float).      #
  28. #                                                                             #
  29. #             2. execute this script using Dust                               #
  30. #             3. execute this programm writing "PExample >pex.bat"            #
  31. #             4. execute the created file "pex.bat" using Dust"               #
  32. #             5. That's it (You got 12 particle objects).                     #
  33. #                                                                             #
  34. #-----------------------------------------------------------------------------#
  35. #                                                                             #
  36. #      Language: ANSI-C                                                       #
  37. #      Compiler: MCPP, GCC (I used 2.6.0)                                     #
  38. # Last modified: 26 September 1994                                            #
  39. #      Problems: none                                                         #
  40. #                                                                             #
  41. ###############################################################################
  42. */
  43. /*
  44. *******************************************************************************
  45. * NOTE: This code is Public Domain. You can do what you want with it.         *
  46. *******************************************************************************
  47. */
  48. #include <stdio.h>
  49. #include <math.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52.  
  53. const ZERO=0.0001;
  54. struct Vector{float x;float y;float z;};
  55. struct LVector{long x;long y;long z;};
  56. int oCount;  /* number of particles (to be read) */
  57. struct LVector* lpos; /*temporary array (to be read)*/
  58. struct Vector* pos; /* particle positions ("decrypted" lpos) */
  59. float bb;           /* needed by RND2() */
  60. int i,j; 
  61. float centreX,centreY,centreZ; /* centre of all particles */
  62.  
  63. /*
  64. *******************************************************************************
  65. * returns a factor between 0.9 and 1.0                                        *
  66. *******************************************************************************
  67. */
  68. float RND2()
  69. {
  70.  bb=(float) rand();
  71.  bb=bb/(float) RAND_MAX*900.0;
  72.  bb=bb+100.0;
  73.  bb=bb/10000.0;
  74.  if (rand()>16384) {return 1.0+bb;} else {return 1.0-bb;}
  75. }
  76. /*
  77. *******************************************************************************
  78. * generates a filename like "obj.0235"                                        * 
  79. *******************************************************************************
  80. */
  81. void GenFn(char* str1,int tt)
  82. {
  83.  printf("%s.",str1);
  84.  if (tt<1000) printf("0");
  85.  if (tt<100) printf("0");
  86.  if (tt<10) printf("0");
  87.  printf("%d",tt);
  88. }
  89. /*
  90. *******************************************************************************
  91. * Read (x,y,z)-array from EXFILE; this example: pos                           *
  92. *******************************************************************************
  93. */
  94. int ReadReal(char* fn,void* addr,int count)
  95. {
  96.  FILE* fh;
  97.  long len;
  98.  fh=fopen(fn,"r");
  99.  if (fh==NULL) return 1;
  100.  len=fread(addr,sizeof(struct Vector),count,fh);
  101.  fclose(fh);
  102.  if (len!=count) return 1;
  103.  return 0;
  104. }
  105. /*
  106. *******************************************************************************
  107. * Read a integer from EXFILE; this example: oCount                            *
  108. *******************************************************************************
  109. */
  110. int ReadInt(char* fn,void* addr)
  111. {
  112.  FILE* fh;
  113.  long len;
  114.  fh=fopen(fn,"rb");
  115.  if (fh==NULL) return 1;
  116.  len=fread(addr,2,1,fh);
  117.  fclose(fh);
  118.  if (len!=1) {return 1;} else {return 0;}
  119. }
  120. /*
  121. *******************************************************************************
  122. * Call the SETPxxx-Procedure of Dust to change the vector vp^[ind];           *
  123. * this example: SETPPOS(1,ind,pos^[ind].x,pos^[ind].x,pos^[ind].z)            *
  124. *******************************************************************************
  125. */
  126. void WritePXXX(float x,float y,float z,int ind,char* cmd)
  127. {
  128.  printf("\nSETP%s(1,%d,%f,%f,%f)",cmd,ind,x,y,z);
  129. }
  130. /*
  131. *******************************************************************************
  132. * Main procedure                                                              *
  133. *  Arguments:                                                                 *
  134. *    frames: number of objects (frames)                                       *
  135. *        fn: base filename of the objects                                     *
  136. *     timep: time to process                                                  *
  137. *        gp: gravity constant, e.g. -10.0 (negative)                          *
  138. *      etap: friction (Stokes), e.g. -0.00001 (negative)                      *
  139. *      vv0p: speed at t=0 (positive)                                          *
  140. *       fmt: save-format-string, e.g. "TDDD"                                  *
  141. *                                                                             *
  142. *******************************************************************************
  143. */
  144. /*
  145. *******************************************************************************
  146. * calculates centre of all poarticles                                         *
  147. *******************************************************************************
  148. */
  149. void getCentre(float ggg)
  150. {
  151.  float xmin,xmax,ymin,ymax,zmin,zmax;
  152.  xmin=pos[0].x;xmax=xmin;ymin=pos[0].y;ymax=ymin;zmin=pos[0].z;zmax=zmin;
  153.  for(i=1;i<oCount;i++) {
  154.   if (xmin>pos[i].x) xmin=pos[i].x;
  155.   if (xmax<pos[i].x) xmax=pos[i].x;
  156.   if (ymin>pos[i].y) ymin=pos[i].y;
  157.   if (ymax<pos[i].y) ymax=pos[i].y;
  158.   if (zmin>pos[i].z) zmin=pos[i].z;
  159.   if (zmax<pos[i].z) zmax=pos[i].z;
  160.  }
  161.  centreX=xmin+(xmax-xmin)/2.0;
  162.  centreY=ymin+(ymax-ymin)/2.0;
  163.  centreZ=zmin+(zmax-zmin)/2.0;
  164.  /* move the object into the positive z-space if necessary */
  165.  if ((zmin<0) && (ggg!=0.0)) {
  166.   xmin=1.1*zmin;
  167.   for(i=0;i<oCount;i++) {
  168.    pos[i].z=pos[i].z-xmin;
  169.   }
  170.   zmin=zmin-xmin;
  171.   zmax=zmax-xmin;
  172.   /* update centreZ */
  173.   centreZ=zmin+(zmax-zmin)/2.0;
  174.   /* change the original object */
  175.   printf("\n;move the object into the positive z-space");
  176.   for(i=0;i<oCount;i++) {
  177.    WritePXXX(pos[i].x,pos[i].y,pos[i].z,i,"POS");
  178.   }
  179.  }
  180. }
  181.  
  182. void DoIt(int frames,char* fn,float timep,float gp,float etap,float vv0p,char* fmt)
  183. {
  184.  struct Vector *v0;
  185.  float *oldX,*oldY;
  186.  float eta,g,vv0,time,timestep,t,A,Ae,Aet,V0,X0,hh;
  187.  float dx,dy,dz,vb,cx,cy,cz,newX,newY,newZ;
  188.  float e1,e2,e3,e4,e5,e6;
  189.  if (frames<1) return;
  190.  /* allocate some arrays */
  191.  v0=(struct Vector*)calloc(oCount,sizeof(struct Vector));
  192.  if (v0==NULL) return;
  193.  oldX=(float*)calloc(oCount,sizeof(float));
  194.  if (oldX==NULL) {free(v0);return;}
  195.  oldY=(float*)calloc(oCount,sizeof(float));
  196.  if (oldY==NULL) {free(oldX);free(v0);return;}
  197.  time=timep;
  198.  g=gp;
  199.  eta=etap;
  200.  vv0=vv0p;
  201.  if (g>0.0) {printf("\ng-error.\n");g=-10.0;}
  202.  if (vv0<ZERO) {printf("\nvv0-error.\n");vv0=1.0;}
  203.  if (eta>=0.0) {printf("\neta-error.\n");eta=-0.00001;}
  204.  getCentre(g);
  205.  
  206.  /* compute speed at t=0 (vectors) */
  207.  for(i=0;i<oCount;i++) {
  208.   dx=pos[i].x-centreX;
  209.   dy=pos[i].y-centreY;
  210.   dz=pos[i].z-centreZ;
  211.   vb=dx*dx;
  212.   vb=vb+dy*dy;
  213.   vb=vb+dz*dz;
  214.   vb=sqrt(vb);
  215.   e1=RND2();
  216.   e2=RND2();
  217.   e3=RND2();
  218.   v0[i].x=dx/vb*vv0*e1;
  219.   v0[i].y=dy/vb*vv0*e2;
  220.   v0[i].z=dz/vb*vv0*e3;
  221.  }
  222.  
  223.  /* generate filename and say "save it" (first and unchanged object) */
  224.  if (!strcmp(fmt,"TDDD")) {printf("\nSavePTDDD(1,");}
  225.  else {
  226.   if (!strcmp(fmt,"VS")) {printf("\nSavePVS(1,");} else {printf("\nSaveP(1,");}
  227.  }
  228.  GenFn(fn,1);
  229.  printf(")");
  230.  
  231.  /* main loop */
  232.  timestep=time/(frames-1);
  233.  for(i=1;i<frames;i++) {
  234.  
  235.   /* output frame as comment */
  236.   printf("\n;frame %d",i);
  237.  
  238.   t=i*timestep; /* actual time */
  239.  
  240.   for(j=0;j<oCount;j++) {
  241.  
  242.    /* particle-size (friction) (to calculate this the array PSCL is needed) */
  243.    e1=RND2();
  244.    A=e1*10.0;
  245.    Ae=A*eta;
  246.    Aet=Ae*t;
  247.    hh=exp(Aet);
  248.  
  249.    /* compute x-coordinate */
  250.    V0=v0[j].x;
  251.    X0=pos[j].x;
  252.    cx=X0*Ae-V0;
  253.    cx=cx+V0*hh;
  254.    cx=cx/Ae;
  255.  
  256.    /* compute y-coordinate */
  257.    V0=v0[j].y;
  258.    X0=pos[j].y;
  259.    cy=X0*Ae-V0;
  260.    cy=cy+V0*hh;
  261.    cy=cy/Ae;
  262.  
  263.    /* compute z-coordinate */
  264.    V0=v0[j].z;
  265.    X0=pos[j].z;
  266.    cz=X0*Ae*Ae-g;
  267.    cz=cz-V0*Ae;
  268.    cz=cz+g*hh;
  269.    cz=cz+V0*Ae*hh;  
  270.    cz=cz-g*Aet;
  271.    cz=cz/(Ae*Ae);
  272.    /* motion must stop at z=0 */
  273.    if (cz>0.0) {
  274.     oldX[j]=cx;
  275.     oldY[j]=cy;
  276.    }
  277.    else {
  278.     cz=0.0;
  279.     if (i>1) {
  280.      cx=oldX[j];
  281.      cy=oldY[j];
  282.     }
  283.     else {
  284.      oldX[j]=cx;
  285.      oldY[j]=cy;
  286.     }
  287.    }
  288.  
  289.    /* the final posion */
  290.    newX=cx;
  291.    newY=cy;
  292.    newZ=cz;
  293.  
  294.    /* say: "apply them" */
  295.    WritePXXX(newX,newY,newZ,j,"POS");
  296.  
  297.   }
  298.   
  299.   /* generate filename and say "save it" */
  300.   if (!strcmp(fmt,"TDDD")) {printf("\nSavePTDDD(1,");}
  301.   else {
  302.    if (!strcmp(fmt,"VS")) {printf("\nSavePVS(1,");} else {printf("\nSaveP(1,");}
  303.   }
  304.   GenFn(fn,i+1);
  305.   printf(")");
  306.  
  307.  }
  308.  
  309.  /* clean up */
  310.  free(oldY);free(oldX);free(v0);
  311. }
  312.  
  313. void main()
  314. {
  315.  /* load the ppos-array */
  316.  if (ReadInt("shit:tmp/PEXAMPLE.OCOUNT",&oCount)==0) {
  317.   oCount=oCount/65536;
  318.   lpos=(struct LVector*)calloc(oCount,sizeof(struct LVector));
  319.   if (lpos==NULL) {
  320.    printf("\nCouldn't allocate temporary PPOS-array.\n");
  321.   }
  322.   else
  323.   { 
  324.    if (ReadReal("shit:tmp/PEXAMPLEGCC.PPOS",&lpos[0],oCount)==0) {
  325.     /* "decrypt" it */
  326.     pos=(struct Vector*)calloc(oCount,sizeof(struct Vector));
  327.     if (pos==NULL) {
  328.      free(lpos);
  329.      printf("\nCouldn't allocate PPOS-array.\n");
  330.     } 
  331.     else {
  332.      for(i=0;i<oCount;i++) {
  333.       pos[i].x=(float)lpos[i].x / 65536.0;
  334.       pos[i].y=(float)lpos[i].y / 65536.0;
  335.       pos[i].z=(float)lpos[i].z / 65536.0;
  336.      }
  337.      /* tell Dust to load the Source-Particle-Object */
  338.      printf("\nloadp(1,PExample.obj)");
  339.      /* do it !*/
  340.      DoIt(12,"obj",12.8,-10.0,-0.001,52,"TDDD");
  341.      /* important*/
  342.      printf("\n");
  343.      free(pos);
  344.     }
  345.    }
  346.    else
  347.    {
  348.     free(lpos);
  349.     printf("\nCouldn't read PPOS-file.\n");
  350.    }
  351.   }
  352.  }
  353.  else
  354.  {
  355.   printf("\nCouldn't read OCOUNT-file.\n");
  356.  }
  357. }
  358.  
  359.